#include <gl/glut.h>
#include <cmath>
#include <iostream>

// 定义天体结构
struct CelestialBody {
    float x, y, z;       // 位置
    float vx, vy, vz;    // 速度
    float mass;          // 质量
    float radius;        // 半径
    float color[3];      // 颜色
};

// 全局变量：定义天体
CelestialBody sun = { 0, 0, 0, 0, 0, 0, 10000, 10, {1.0, 1.0, 0.0} };  // 太阳
CelestialBody earth = { 0, 0, 0, 0, 0, 0, 100, 5, {0.0, 0.0, 1.0} };  // 地球
CelestialBody moon = { 0, 0, 0, 0, 0, 0, 1, 2, {0.5, 0.5, 0.5} };  // 月球

// 时间变量
float elapsedTime = 0.0;

// 更新天体位置
void updatePositions() {
    // 地球绕太阳的圆周运动
    float earthOrbitRadius = 150.0;  // 地球轨道半径
    earth.x = earthOrbitRadius * cos(elapsedTime);
    earth.y = earthOrbitRadius * sin(elapsedTime);

    // 月球绕地球的圆周运动
    float moonOrbitRadius = 30.0;  // 月球轨道半径
    moon.x = earth.x + moonOrbitRadius * cos(elapsedTime * 2);  // 月球运动速度更快
    moon.y = earth.y + moonOrbitRadius * sin(elapsedTime * 2);
}

// 渲染天体
void renderBody(const CelestialBody& body) {
    glColor3fv(body.color);  // 设置颜色
    glPushMatrix();          // 保存当前矩阵状态
    glTranslatef(body.x, body.y, body.z);  // 移动到天体位置
    glutSolidSphere(body.radius, 20, 20);  // 使用 GLUT 提供的函数绘制球体
    glPopMatrix();  // 恢复矩阵状态
}

// 初始化 OpenGL 环境
void initOpenGL() {
    glEnable(GL_DEPTH_TEST);  // 启用深度测试
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  // 设置背景颜色为黑色
}

// 设置视图和投影矩阵
void reshape(int width, int height) {
    glViewport(0, 0, width, height);  // 设置视口大小
    glMatrixMode(GL_PROJECTION);      // 切换到投影矩阵模式
    glLoadIdentity();                 // 重置投影矩阵
    gluPerspective(45.0, (float)width / height, 0.1, 10000.0);  // 设置透视投影

    glMatrixMode(GL_MODELVIEW);       // 切换到模型视图矩阵模式
    glLoadIdentity();                 // 重置模型视图矩阵
    gluLookAt(0.0, 0.0, 500.0,  // 相机位置
        0.0, 0.0, 0.0,    // 观察目标点
        0.0, 1.0, 0.0);   // 上方向
}

// 显示回调函数
void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // 清空颜色和深度缓冲区

    // 更新天体位置
    updatePositions();

    // 渲染天体
    renderBody(sun);
    renderBody(earth);
    renderBody(moon);

    glutSwapBuffers();  // 交换前后缓冲区

    // 增加时间变量
    elapsedTime += 0.01;
}

// 主函数
int main(int argc, char** argv) {
    // 初始化 GLUT
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Celestial Motion Simulation");

    // 初始化 OpenGL 环境
    initOpenGL();

    // 设置显示回调函数
    glutDisplayFunc(display);
    glutIdleFunc(display);  // 设置空闲回调函数，用于动画效果
    glutReshapeFunc(reshape);  // 设置窗口大小调整回调函数

    // 进入 GLUT 主循环
    glutMainLoop();
    return 0;
}